package com.ganxiang.ximenhong.model;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;

import com.ganxiang.ximenhong.R;
import com.ganxiang.ximenhong.bean.LoginInfo;
import com.ganxiang.ximenhong.config.Configs;
import com.ganxiang.ximenhong.util.Utils;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;




public class DataLoader {

	private static DataLoader loader;
	private HashMap<String, Task> mTaskMap = new HashMap<String, Task>();
	private Context mContext;
	public static boolean isRefresh = false;
	public JSONObject mUserInfo;
	public JSONArray mBookSelfArray;
	public int mShoppingCarNum;
	private static File tempFile = null;
	private LoginInfo mLoginInfo;

	private DataLoader(Context context) {
		mContext = context.getApplicationContext();
	}

	public static DataLoader getInstance(Context context) {
		if (loader == null) {
			loader = new DataLoader(context);
		}
		return loader;
	}

	/**
	 * 获取各个接口的url
	 * 
	 * @param type
	 * @return
	 */
	public static String getMethodUrl(TaskType type) {
		String url = Configs.ServerUrl;
		switch (type) {
		// 用户注册，登陆
		case TaskType_Login_getTelCode:// 1 获取短信验证�?
			url += "API/index.php?action=Login&do=getTelCode";
			break;
		case TaskType_Login_Reg:// 2 用户注册
			url += "API/index.php?action=Login&do=Reg";
			break;
		case TaskType_Login_Index:// 3 用户登陆
			url += "API/index.php?action=Login&do=Index";
			break;
		case TaskType_Login_fnishInfo:// 
			url += "API/index.php?action=User&do=finishInfo";
			break;
		

		default:
			break;
		}
		return url;
	}

	public HashMap<String, Task> getTaskMap() {
		return mTaskMap;
	}

	public void cancelTask(TaskListener type, TaskListener listener) {
		if (mTaskMap.containsKey(type + "" + listener.hashCode())) {
			mTaskMap.get(type + "" + listener.hashCode()).cancelTask();
		}
	}

	public void cancelAllTask() {
		for (Task task : mTaskMap.values()) {
			task.cancelTask();
		}
	}

	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	@SuppressLint("NewApi")
	public void startTask(HashMap<String, Object> params, TaskListener listener) {
		TaskType type = (TaskType) params.get("taskType");
		if (listener == null) {
			Task task = new Task(mContext, listener, params);
			if (Utils.getAndroidSDKVersion() >= 11) {
				task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
			} else {
				task.execute();
			}
		} else if (!mTaskMap.containsKey(type + "" + listener.hashCode())) {
			Task task = new Task(mContext, listener, params);
			mTaskMap.put(type + "" + listener.hashCode(), task);
			if (Utils.getAndroidSDKVersion() >= 11) {
				task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
			} else {
				task.execute();
			}
		}
	}

	public Object getResult(HashMap<String, Object> params, Task task,
			boolean isRequest) {
		TaskType type = (TaskType) params.get("taskType");
		String urlStr = getMethodUrl(type);

		boolean isPost = true;
		boolean first = false;
		String postParams = isPost ? "" : null;
		JSONArray jsonArray = null;
		for (Map.Entry<String, Object> entry : params.entrySet()) {
			String key = entry.getKey();
			if (key.startsWith("jsonarr_")) {
				jsonArray = (JSONArray) entry.getValue();
			}
			if (key.startsWith("params_")) {
				if (first) {
					first = false;
					if (!isPost) {
						urlStr += "?";
					}
				}
				if (entry.getValue() != null) {
					String tmp = null;
					try {
						tmp = ("&" + key.substring(key.indexOf("_") + 1) + "=" + URLEncoder
								.encode(entry.getValue() + "", "utf-8"));
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
					if (!isPost) {
						urlStr += tmp;
					} else {
						postParams += tmp;
					}
				}
			}
		}
		// if (postParams != null && postParams.endsWith("&")) {
		// postParams = postParams.substring(0, postParams.lastIndexOf("&"));
		// }
		InputStream inStream = null;
		HttpURLConnection con = null;
		try {
			URL url = new URL(urlStr);
			System.out.println("url====" + urlStr);
			con = (HttpURLConnection) url.openConnection();
			params.put("connection", con);
			if (isRequest) {
				String pStr = String
						.format("%s/%s (Android; %s; %sx%s)",
								Build.MODEL,
								Utils.getVersionNumber(mContext),
								Utils.getAndroidSDKVersionName(),
								mContext.getResources().getDisplayMetrics().widthPixels,
								mContext.getResources().getDisplayMetrics().heightPixels);
				con.setRequestProperty("User-Agent", pStr);
				con.setRequestProperty("XPS-Devicename", Build.MODEL);
				con.setRequestProperty("XPS-ID", Utils.getHardwareID(mContext));
				con.setRequestProperty("XPS-Version",
						Utils.getVersionNumber(mContext) + "");

				for (Map.Entry<String, Object> entry : params.entrySet()) {
					String key = entry.getKey();
					if (key.startsWith("header_")) {
						con.setRequestProperty(
								key.substring(key.indexOf("_") + 1),
								(String) entry.getValue());
					}
				}
			}

			if (isPost) {
				con.setRequestProperty("content-type",
						"application/x-www-form-urlencoded");
				con.setDoOutput(true);
				con.setDoInput(true);
				con.setRequestMethod("POST");
				if (postParams != null) {
					DataOutputStream outStream = new DataOutputStream(
							con.getOutputStream());
					outStream.write(postParams.getBytes());
					if (null != jsonArray) {
						System.out.println("---" + jsonArray.toString());
					}
				}
				con.getOutputStream().flush();
				con.getOutputStream().close();
				System.out.println("===postStr " + postParams);
			}
			con.setConnectTimeout(Configs.NetConnectTimeout);
			con.setReadTimeout(Configs.NetReadTimeout);
			int code = con.getResponseCode();
			System.out.println("====code> " + code);
			inStream = con.getInputStream();
		} catch (Exception e) {
			int responseCode = 0;
			try {
				responseCode = con.getResponseCode();
			} catch (IOException e2) {
				e2.printStackTrace();
			}
			e.printStackTrace();
			if (!Utils.isInternetAvaiable(mContext)) {
				return new Error(mContext.getString(R.string.message_not_net));
			}
			if (e instanceof IOException) {
				return new Error(mContext.getString(R.string.message_not_visit) + responseCode + e.getMessage());
			}
			e.printStackTrace();
			System.out.println("result===" + e.getLocalizedMessage() + " "+ urlStr);
			return new Error(e.getMessage() + responseCode);
		}
		JSONObject jsObj = Utils.getJsonFromInputStream(inStream);


		if (jsObj != null) {
			if (jsObj.has("code") && jsObj.optInt("code") != 1) {
				return new Error(jsObj.optString("msg"));
			}
		}
		if (type == TaskType.TaskType_Login_Index) {

			LoginInfo loginInfo = new LoginInfo(); 
			 
			loginInfo.userId = jsObj.optString("id");
			loginInfo.userToken = jsObj.optString("1234");
			if (null != con.getHeaderField("Date")) {
				loginInfo.serviceTime = new Date(con.getHeaderField("Date"));
			}
			saveLoginInfo(loginInfo);
			MessageManager.getInstance().sendMessage(
					MessageManager.MessageType_Login, null);
			return loginInfo;

		}
		return jsObj;
	}

	public void saveLoginInfo(LoginInfo info) {
		this.mLoginInfo = info;
		CacheHandler.getInstance().saveLoginInfo(mContext, info);
	}

	public JSONArray joinJSONArray(JSONArray old, JSONArray news) {
		if (old == null && news == null) {
			return null;
		}
		if (old == null) {
			return news;
		}
		if (news == null) {
			return old;
		}
		StringBuffer buffer = new StringBuffer();
		try {
			int len = old.length();
			for (int i = 0; i < len; i++) {
				JSONObject obj1 = (JSONObject) old.get(i);
				if (i == len - 1)
					buffer.append(obj1.toString());
				else
					buffer.append(obj1.toString()).append(",");
			}
			len = news.length();
			if (len > 0)
				buffer.append(",");
			for (int i = 0; i < len; i++) {
				JSONObject obj1 = (JSONObject) news.get(i);
				if (i == len - 1)
					buffer.append(obj1.toString());
				else
					buffer.append(obj1.toString()).append(",");
			}
			buffer.insert(0, "[").append("]");
			return new JSONArray(buffer.toString());
		} catch (Exception e) {
		} catch (OutOfMemoryError e) {
		}
		return null;
	}
	
	public LoginInfo getLoginInfo() {
		if (mLoginInfo == null) {
			mLoginInfo = CacheHandler.getInstance().getLoginInfo(
					mContext);
		}

		return mLoginInfo;
	}
	
	public JSONObject getUserInfo() {
		if (mUserInfo == null) {
			CacheHandler.getInstance().getUserInfo(mContext);
		}
		return mUserInfo;
	}

}
